"""
Case Type   : CM_Tools
Case Name   : cm_ctl start/stop启动数据库基本参数验证
Create At   : 2025/5/20
Owner       : ningyali
Description :
    1.一主多备数据库部署模式下启动/停止所有数据库服务
    2.启动/停止单个主机上的所有实例（含CM）
    3.单独启动/停止某个实例进程（数据库进程）
    4.启动/停止整个AZ
    5.重复停止所有/某个实例
    6.重复启动所有/某个实例
    7.&&连接使用
    8.停止单机所有实例后，单独拉起某个实例进程
Expect      :
    1.执行成功
    2.执行成功
    3.执行成功
    4.执行成功
    5.执行成功
    6.执行成功
    7.执行成功
    8.停止所有实例成功，单独拉起某个实例进程失败
History     :
"""

import os
import time
import unittest

from testcase.utils.ComInstall import CmInstall
from testcase.utils.ComInstall import CmUnInstall
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class CMServer(unittest.TestCase):
    def setUp(self):
        self.log = Logger()
        self.log.info(f'-----{os.path.basename(__file__)} start-----')
        self.pri_sh = CommonSH('PrimaryDbUser')
        self.root_nodes = (Node('PrimaryRoot'), Node('Standby1Root'),
                           Node('Standby2Root'))
        self.user_nodes = (Node('PrimaryDbUser'), Node('Standby1DbUser'),
                           Node('Standby2DbUser'))
        self.common = Common()
        self.constant = Constant()

        text = '----prestep1:安装cm;expect:执行成功----'
        self.log.info(text)
        self.install_pkg_path = os.path.dirname(macro.DB_SCRIPT_PATH)
        self.cm = CmInstall(self.install_pkg_path, self.pri_sh.node.ssh_user)
        res = self.cm.update_xml_for_cm(*self.root_nodes)
        self.assertGreater(res.count('cmDir'), 1, f'执行失败: {text}')

        res = self.cm.cm_install(self.user_nodes[0])
        self.assertIn('Install CM tool success', res, f'执行失败: {text}')

    def test_trans(self):
        text = '----step1:一主多备数据库部署模式下启动/停止所有数据库服务;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};cm_ctl stop; cm_ctl start"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn(self.constant.cm_stop_success_msg, q_res, f'执行失败: {text}')
        self.assertIn(self.constant.cm_start_success_msg, q_res,
                      f'执行失败: {text}')

        text = '----step2:启动/停止单个主机上的所有实例（含CM）;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop -n 1; cm_ctl start -n 1"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn('cm_ctl: stop node successfully', q_res, f'执行失败: {text}')
        self.assertIn('cm_ctl: start node successfully', q_res, f'执行失败: {text}')

        text = '----step3:单独启动/停止某个实例进程（数据库进程）;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop -n 1 -D {macro.DB_INSTANCE_PATH}; " \
                f"cm_ctl start -n 1 -D {macro.DB_INSTANCE_PATH}"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn('cm_ctl: stop instance successfully', q_res,
                      f'执行失败: {text}')
        self.assertIn('cm_ctl: start instance successfully', q_res,
                      f'执行失败: {text}')

        text = '----step4:启动/停止整个AZ;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop -z ALL; cm_ctl start -z ALL"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn(self.constant.cm_stop_success_msg, q_res, f'执行失败: {text}')
        self.assertIn(self.constant.cm_start_success_msg, q_res,
                      f'执行失败: {text}')

        text = '----step5:重复停止所有/某个实例;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop -n 1; cm_ctl stop -n 1"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertEqual(q_res.count('cm_ctl: stop node successfully'), 2,
                         f'执行失败: {text}')

        text = '----step6:重复启动所有/某个实例;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl start -n 1; cm_ctl start -n 1"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertEqual(q_res.count('cm_ctl: start node successfully'), 2,
                         f'执行失败: {text}')

        text = '----step7:&&连接使用;expect:执行成功----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop && cm_ctl start;" \
                f"cm_ctl stop -n 1 && cm_ctl start -n 1"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn(self.constant.cm_stop_success_msg, q_res, f'执行失败: {text}')
        self.assertIn(self.constant.cm_start_success_msg, q_res,
                      f'执行失败: {text}')
        self.assertIn('cm_ctl: stop node successfully', q_res, f'执行失败: {text}')
        self.assertIn('cm_ctl: start node successfully', q_res, f'执行失败: {text}')

        text = '----step8:停止单机所有实例后，单独拉起某个实例进程;' \
               'expect:停止所有实例成功，单独拉起某个实例进程失败----'
        self.log.info(text)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl stop -n 1; " \
                f"cm_ctl start -n 1 -D {macro.DB_INSTANCE_PATH}"
        q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
        self.assertIn('cm_ctl: stop node successfully', q_res, f'执行失败: {text}')
        self.assertNotIn('cm_ctl: start instance successfully', q_res,
                         f'执行失败: {text}')

    def tearDown(self):
        text = '----poststep1:还原数据库;expect:执行成功----'
        self.log.info(text)
        start_cmd = f"source {macro.DB_ENV_PATH};cm_ctl start -n 1"
        start_res = self.common.get_sh_result(self.user_nodes[0], start_cmd)
        q_cmd = f"source {macro.DB_ENV_PATH};" \
                f"cm_ctl query -v -C -i -d"
        q_res = ''
        for i in range(10):
            time.sleep(10)
            q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)
            if 'Standby Normal' in q_res.splitlines()[-1].split('|')[1]:
                break
            elif 'Standby Normal' in q_res.splitlines()[-1].split('|')[0]:
                switch_cmd = f"source {macro.DB_ENV_PATH};cm_ctl switchover -a;"
                self.common.get_sh_result(self.user_nodes[0], switch_cmd)
                time.sleep(5)
                q_res = self.common.get_sh_result(self.user_nodes[0], q_cmd)

        text = '----poststep2:卸载cm;expect:执行成功----'
        self.log.info(text)
        self.un_cm = CmUnInstall(self.install_pkg_path,
                                 self.pri_sh.node.ssh_user)
        res = self.un_cm.cm_uninstall(
            self.user_nodes[0], '--deleteData --deleteBinary')

        self.assertIn('cm_ctl: start node successfully', start_res,
                      f'执行失败: {text}')
        self.assertTrue(
            'Primary Normal' in q_res and q_res.count('Standby Normal') == 2,
            f'执行失败: {text}')
        self.assertIn('Uninstall CM tool success', res, f'执行失败: {text}')
        self.log.info(f'-----{os.path.basename(__file__)} end-----')
